package com.blog.cmrpersonalblog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blog.cmrpersonalblog.dto.user.request.UserActivityQueryRequest;
import com.blog.cmrpersonalblog.dto.user.response.AdminUserProfileResponse;
import com.blog.cmrpersonalblog.entity.UserActivity;
import com.blog.cmrpersonalblog.enums.ActivityType;
import com.blog.cmrpersonalblog.mapper.UserActivityMapper;
import com.blog.cmrpersonalblog.service.UserActivityService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户活动记录服务实现类
 */
@Slf4j
@Service
public class UserActivityServiceImpl implements UserActivityService {

   @Resource
    private UserActivityMapper userActivityMapper;

    @Override
    public void recordActivity(Long userId, ActivityType activityType, String description, 
                              Long targetId, String targetType, String ipAddress, 
                              String userAgent, String result, String extraData) {
        try {
            // 检查是否应该记录该活动
            if (!shouldRecord(activityType, userId)) {
                return;
            }

            UserActivity activity = new UserActivity();
            activity.setUserId(userId);
            activity.setActivityType(activityType.getCode());
            activity.setActivityDescription(description != null ? description : activityType.getDescription());
            activity.setTargetId(targetId);
            activity.setTargetType(targetType);
            activity.setIpAddress(ipAddress);
            activity.setUserAgent(userAgent);
            activity.setResult(result != null ? result : "SUCCESS");
            activity.setExtraData(extraData);
            activity.setCreateTime(LocalDateTime.now());

            userActivityMapper.insert(activity);
            
            log.debug("记录用户活动: userId={}, type={}, description={}", 
                     userId, activityType.getCode(), description);
        } catch (Exception e) {
            log.warn("记录用户活动失败: userId={}, type={}, error={}", 
                    userId, activityType.getCode(), e.getMessage());
        }
    }

    @Override
    public void recordActivity(Long userId, ActivityType activityType, String description,
                              String ipAddress, String userAgent) {
        recordActivity(userId, activityType, description, null, null,
                      ipAddress, userAgent, "SUCCESS", null);
    }

    @Override
    public void recordActivity(Long userId, String activityType, String description,
                              Long targetId, String targetType, String result,
                              Map<String, Object> extraData) {
        try {
            UserActivity activity = new UserActivity();
            activity.setUserId(userId);
            activity.setActivityType(activityType);
            activity.setActivityDescription(description);
            activity.setTargetId(targetId);
            activity.setTargetType(targetType);
            activity.setResult(result != null ? result : "SUCCESS");

            // 转换extraData为JSON字符串
            if (extraData != null && !extraData.isEmpty()) {
                try {
                    StringBuilder json = new StringBuilder("{");
                    boolean first = true;
                    for (Map.Entry<String, Object> entry : extraData.entrySet()) {
                        if (!first) json.append(",");
                        json.append("\"").append(entry.getKey()).append("\":");
                        if (entry.getValue() instanceof String) {
                            json.append("\"").append(entry.getValue()).append("\"");
                        } else {
                            json.append(entry.getValue());
                        }
                        first = false;
                    }
                    json.append("}");
                    activity.setExtraData(json.toString());
                } catch (Exception e) {
                    log.warn("转换extraData为JSON失败: {}", e.getMessage());
                    activity.setExtraData("{}");
                }
            }

            activity.setCreateTime(LocalDateTime.now());

            userActivityMapper.insert(activity);

            log.debug("记录用户活动: userId={}, type={}, description={}",
                     userId, activityType, description);
        } catch (Exception e) {
            log.warn("记录用户活动失败: userId={}, type={}, error={}",
                    userId, activityType, e.getMessage());
        }
    }

    @Override
    public void recordLoginActivity(Long userId, boolean success, String ipAddress, 
                                   String userAgent, String failureReason) {
        if (success) {
            recordActivity(userId, ActivityType.LOGIN, "用户登录成功", 
                          ipAddress, userAgent);
        } else {
            String description = "用户登录失败";
            if (failureReason != null && !failureReason.isEmpty()) {
                description += ": " + failureReason;
            }
            recordActivity(userId, ActivityType.LOGIN_FAILED, description, 
                          null, null, ipAddress, userAgent, "FAILED", 
                          "{\"reason\":\"" + failureReason + "\"}");
        }
    }

    @Override
    public IPage<AdminUserProfileResponse.ActivityRecord> getActivityPage(UserActivityQueryRequest query) {
        try {
            Page<AdminUserProfileResponse.ActivityRecord> page = new Page<>(query.getPage(), query.getSize());
            return userActivityMapper.selectActivityPage(page, query);
        } catch (Exception e) {
            log.error("分页查询用户活动记录失败: query={}", query, e);
            throw new RuntimeException("查询活动记录失败", e);
        }
    }

    @Override
    public List<AdminUserProfileResponse.ActivityRecord> getRecentActivities(Long userId, Integer limit) {
        try {
            return userActivityMapper.selectRecentActivities(userId, limit);
        } catch (Exception e) {
            log.warn("获取用户最近活动记录失败: userId={}, error={}", userId, e.getMessage());
            return List.of();
        }
    }

    @Override
    public AdminUserProfileResponse.SecurityInfo getUserSecurityInfo(Long userId) {
        try {
            return userActivityMapper.selectUserSecurityInfo(userId);
        } catch (Exception e) {
            log.warn("获取用户安全信息失败: userId={}, error={}", userId, e.getMessage());
            AdminUserProfileResponse.SecurityInfo defaultInfo = new AdminUserProfileResponse.SecurityInfo();
            defaultInfo.setLastLoginIp("");
            defaultInfo.setLastLoginLocation("");
            defaultInfo.setLastLoginDevice("");
            defaultInfo.setRecentLoginIps(List.of());
            defaultInfo.setSuspiciousLoginCount(0);
            defaultInfo.setIsEmailVerified(false);
            defaultInfo.setIsPhoneVerified(false);
            defaultInfo.setPasswordLastChanged(null);
            return defaultInfo;
        }
    }

    @Override
    public AdminUserProfileResponse.InteractionInfo getUserInteractionInfo(Long userId, Integer days) {
        try {
            return userActivityMapper.selectUserInteractionInfo(userId);
        } catch (Exception e) {
            log.warn("获取用户互动信息失败: userId={}, error={}", userId, e.getMessage());
            AdminUserProfileResponse.InteractionInfo defaultInfo = new AdminUserProfileResponse.InteractionInfo();
            defaultInfo.setLastLoginTime(null);
            defaultInfo.setLastActiveTime(null);
            defaultInfo.setLoginDays(0);
            defaultInfo.setAvgDailyActiveTime(0.0);
            defaultInfo.setTotalSessions(0);
            defaultInfo.setActiveTimeRanges(List.of());
            return defaultInfo;
        }
    }

    @Override
    public Integer cleanExpiredActivities() {
        try {
            int totalCleaned = 0;
            for (ActivityType type : ActivityType.values()) {
                totalCleaned += cleanExpiredActivities(type);
            }
            log.info("清理过期活动记录完成，共清理{}条记录", totalCleaned);
            return totalCleaned;
        } catch (Exception e) {
            log.error("清理过期活动记录失败", e);
            return 0;
        }
    }

    @Override
    public Integer cleanExpiredActivities(ActivityType activityType) {
        try {
            LocalDateTime beforeTime = LocalDateTime.now().minusDays(activityType.getRetentionDays());
            LambdaQueryWrapper<UserActivity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserActivity::getActivityType, activityType.getCode())
                   .lt(UserActivity::getCreateTime, beforeTime);
            
            int count = userActivityMapper.delete(wrapper);
            if (count > 0) {
                log.debug("清理{}类型的过期活动记录{}条", activityType.getCode(), count);
            }
            return count;
        } catch (Exception e) {
            log.warn("清理{}类型的过期活动记录失败: {}", activityType.getCode(), e.getMessage());
            return 0;
        }
    }

    @Override
    public Map<String, Object> getActivityStatistics(Long userId, Integer days) {
        try {
            Map<String, Object> stats = new HashMap<>();
            LocalDateTime startTime = LocalDateTime.now().minusDays(days);
            
            LambdaQueryWrapper<UserActivity> wrapper = new LambdaQueryWrapper<>();
            if (userId != null) {
                wrapper.eq(UserActivity::getUserId, userId);
            }
            wrapper.ge(UserActivity::getCreateTime, startTime);
            
            // 总活动数
            Long totalActivities = userActivityMapper.selectCount(wrapper);
            stats.put("totalActivities", totalActivities);

            // 成功操作数
            wrapper.eq(UserActivity::getResult, "SUCCESS");
            Long successActivities = userActivityMapper.selectCount(wrapper);
            stats.put("successActivities", successActivities);

            // 失败操作数
            stats.put("failedActivities", totalActivities - successActivities);

            // 成功率
            double successRate = totalActivities > 0 ? (double) successActivities / totalActivities * 100 : 0;
            stats.put("successRate", Math.round(successRate * 100.0) / 100.0);
            
            return stats;
        } catch (Exception e) {
            log.error("获取活动统计信息失败", e);
            return new HashMap<>();
        }
    }

    @Override
    public boolean shouldRecord(ActivityType activityType, Long userId) {
        // 总是记录重要操作
        if (activityType.isImportant()) {
            return true;
        }
        
        // 对于非重要操作，可以添加额外的过滤逻辑
        // 例如：限制频率、用户类型等
        
        // 检查是否在短时间内有相同类型的操作（防止重复记录）
        try {
            LocalDateTime recentTime = LocalDateTime.now().minusMinutes(5);
            LambdaQueryWrapper<UserActivity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserActivity::getUserId, userId)
                   .eq(UserActivity::getActivityType, activityType.getCode())
                   .ge(UserActivity::getCreateTime, recentTime);
            
            Long recentCount = userActivityMapper.selectCount(wrapper);

            // 如果5分钟内已有相同操作，则不记录（避免重复）
            return recentCount == 0;
        } catch (Exception e) {
            log.warn("检查活动记录条件失败，默认记录: {}", e.getMessage());
            return true;
        }
    }
}
